/************************************************************************
 * Copyright (c) 2008 Sergei Stolyarov
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Main window header file.
 ************************************************************************/

#include <QtGui>
#include <QtDebug>

#include <QTimer>
#include <QFile>

#include "controlwindow.h"
#include "configholder.h"
#include "preferencesdialog.h"
#include "aboutdialog.h"
#include "eeecontrol.h"

#define NUM_LOCK_MASK    0x00000002
#define CAPS_LOCK_MASK   0x00000001

static const QString state0("0\n");
static const QString state1("1\n");

ControlWindow::ControlWindow()
    : QDialog()
{

    //this->setAttribute(Qt::WA_DeleteOnClose, true);
    
    ui.setupUi(this);


    // create timer
    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(updateControls()));;

    // create and connect actions
    toggleControlWindowAction = new QAction(tr("Toggle Control Window"), this);
    toggleControlWindowAction->setIcon(QIcon(QString(":images/toggle.png")));
    connect(toggleControlWindowAction, SIGNAL(triggered()), this, SLOT(toggleShow()));

    preferencesAction = new QAction(tr("&Preferences"), this);
    preferencesAction->setIcon(QIcon(QString(":images/preferences.png")));
    connect(preferencesAction, SIGNAL(triggered()), this, SLOT(preferencesDialog()));
 
    aboutAction = new QAction(tr("&About EeeTune"), this);
    aboutAction->setIcon(QIcon(QString(":images/help.png")));
    connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutDialog()));
   
    quitAction = new QAction(tr("&Quit"), this);
    quitAction->setIcon(QIcon(QString(":images/exit.png")));
    connect(quitAction, SIGNAL(triggered()), this, SLOT(quit()));

    // connect slots
    connect(ui.closeButton, SIGNAL(clicked()), this, SLOT(close()));

    // create tray icon menu
    trayIconMenu = new QMenu(this);
    trayIconMenu->addAction(toggleControlWindowAction);
    trayIconMenu->addAction(preferencesAction);
    trayIconMenu->addAction(aboutAction);
    trayIconMenu->addSeparator();
    trayIconMenu->addAction(quitAction);
    trayIconMenu->setActiveAction(toggleControlWindowAction);

    // create tray icon
    trayIcon = new QSystemTrayIcon(this);
    trayIcon->setIcon(QIcon(QString(":images/tray-icon.png")));
    trayIcon->setContextMenu(trayIconMenu);
    trayIcon->setVisible(true);
    trayIcon->setToolTip(QString("EeeTune. Click to show information balloon, \ndouble click to open window, \nright click to open menu."));
    connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
        this, SLOT(trayMenuActivated(QSystemTrayIcon::ActivationReason)));

    numLockOffIcon = new QIcon(QString(":images/num-lock-off.png"));
    numLockOnIcon = new QIcon(QString(":images/num-lock-on.png"));
    numLockTrayIcon = new QSystemTrayIcon(this);
    numLockTrayIcon->setIcon(*numLockOffIcon);

    capsLockOnIcon = new QIcon(QString(":images/caps-lock-on.png"));
    capsLockOffIcon = new QIcon(QString(":images/caps-lock-off.png"));
    capsLockTrayIcon = new QSystemTrayIcon(this);
    capsLockTrayIcon->setIcon(*capsLockOnIcon);
    
    // read some settings and set device parameters according to them
    ConfigHolder* c = ConfigHolder::getInstance();

    if (c->fanManual()) {
        // turn on manual mode
        on_fanControlManual_clicked(true);
        
        int fs = c->fanSpeed();
        if (fs >= 0 && fs <= 100) {
            on_fanSpeed_valueChanged(fs);
        }
    }

    reloadState();
}

/*
QString ControlWindow::getParameterValue(const QString paramName)
{
    ConfigHolder* c = ConfigHolder::getInstance();

    QString ip = c->interfacePoint();

    QString fullPath = ip + QString("/") + paramName;
    QFile dev(fullPath);

    if (!dev.open(QIODevice::ReadOnly)) {
        return QString();
    }

    QByteArray data = dev.readAll();
    dev.close();
    return QString(data);
}

bool ControlWindow::setParameterValue(const QString paramName, QString paramValue)
{
    ConfigHolder* c = ConfigHolder::getInstance();

    QString ip = c->interfacePoint();

    QString fullPath = ip + QString("/") + paramName;
    QFile dev(fullPath);

    if (!dev.open(QIODevice::WriteOnly)) {
        return false;
    }

    qint64 res = dev.write(paramValue.toAscii());
    dev.close();

    return -1 != res;
}
*/

void ControlWindow::closeEvent(QCloseEvent *event)
{
    qDebug() << "DEBUG: ControlWindow::closeEvent() call";
    event->ignore();

    // don't destroy application when closing window just hide
    this->hide();

    // also stop timer
    timer->stop();
}

// slots

/*
 * Update state of all controls (read actual data and set all controls values)
 */
void ControlWindow::updateControls()
{
    qDebug() << "DEBUG: reread device state";
    EeeControl* e = EeeControl::getInstance();

    qDebug() << "DEBUG: fan_manual = " << e->fanMode();

    if (!e->isPortsAvailable()) {
        // disable all controls
        ui.fanGroupBox->setEnabled(false);
        ui.temperatureGroupBox->setEnabled(false);
        return;
    }

    ui.fanGroupBox->setEnabled(true);
    if (EeeControl::FanModeManual == e->fanMode()) {
        // i.e. manual mode is active
        ui.fanControlManual->setChecked(true);
        ui.fanSpeed->setEnabled(true);
    } else {
        // i.e. automatic mode is active
        ui.fanControlAuto->setChecked(true);
        ui.fanSpeed->setEnabled(false);
    }

    // get fan speed in rpm
    ui.fanSpeedRpm->setText(QString::number(e->fanSpeedRpm()));
    //
    // get fan speed in percent
    ui.fanSpeed->setValue(e->fanSpeedPercent());


    // get temperature value
    int temperature = e->temperature();
    qDebug() << "DEBUG: temperature" << temperature;
    if (temperature <= 0 || temperature > 100) {
        //ui.temperatureBar->setValue(0);
        ui.temperatureGroupBox->setEnabled(false);
    } else {
        ui.temperatureBar->setValue(temperature);
        ui.temperatureGroupBox->setEnabled(true);
        ui.temperatureLabel->setText(QString::number(temperature));
    }

}

void ControlWindow::reloadState()
{
    ConfigHolder* c = ConfigHolder::getInstance();

    // show/hide LED icons
    bool show = c->showLedIcons();
    numLockTrayIcon->setVisible(show);
    capsLockTrayIcon->setVisible(show);
}

void ControlWindow::reject()
{
    close();
}

void ControlWindow::show()
{
    QDialog::show();

    // call updateControls() because timer will call it in a few seconds
    updateControls();
    EeeControl* e = EeeControl::getInstance();
    
    if (!e->isPortsAvailable()) {
        // i.e. failed to get info from device
        // stop timer
        // show warning
        //QMessageBox::warning(this, tr("Error"), tr("Unable to read device parameters, application must be launched with superuser privileges. Fan and temperature monitoring features will be disabled. Keyboard LEDs icons are still available though."));
        //timer->stop();
        //close();
    } else {
        // start the timer
        ConfigHolder* c = ConfigHolder::getInstance();

        int r = c->refreshInterval();
        qDebug() << "DEBUG: refresh interval is:" << r;
        if (r <= 0) {
            r = 1;
            // set new refresh interval
            qDebug() << "DEBUG: update refresh interval";
            c->setRefreshInterval(r);
        }
        r *= 1000;
        timer->start(r);

    }
}

void ControlWindow::toggleShow()
{
    if (isVisible()) {
        close();
    } else {
        show();
    }
}

void ControlWindow::preferencesDialog()
{
    // show settings dialog
    PreferencesDialog s(this);
    connect(&s, SIGNAL(trayMenuBalloon(const QString &, const QString &, QSystemTrayIcon::MessageIcon, int)), 
        this, SLOT(trayMenuBalloon(const QString &, const QString &, QSystemTrayIcon::MessageIcon, int)));
    if (QDialog::Accepted == s.exec()) {
        reloadState();
    }
    return;
}

/*
 * Display "About EeeTune" dialog
 */
void ControlWindow::aboutDialog()
{
    AboutDialog about(this);
    about.exec();
}

void ControlWindow::trayMenuActivated(QSystemTrayIcon::ActivationReason reason)
{
    qDebug() << "DEBUG: ControlWindow::trayMenuActivated(QSystemTrayIcon::ActivationReason reason) call";
    EeeControl* e = EeeControl::getInstance();

    switch (reason) {
        case QSystemTrayIcon::DoubleClick:
        case QSystemTrayIcon::MiddleClick:
            toggleShow();
            break;

        case QSystemTrayIcon::Trigger:
            
            // show bubble
            if (!e->isPortsAvailable()) {
                break;
            }
            QString msg("Temperature: %1\nFan speed: %2 rpm (%3%)");
             msg = msg.arg(e->temperature())
                .arg(e->fanSpeedRpm())
                .arg(e->fanSpeedPercent());
            trayIcon->showMessage(QString("EeeTune"), msg);
            break;
    }
}

void ControlWindow::trayMenuBalloon(const QString & title, const QString & message, QSystemTrayIcon::MessageIcon icon, int millisecondsTimeoutHint)
{
    trayIcon->showMessage(title, message, icon, millisecondsTimeoutHint);
}

void ControlWindow::on_fanControlManual_clicked(bool checked)
{
    // enable fanSpeed control
    if (checked) {
       ui.fanSpeed->setEnabled(true);

        // turn on manual fan speed control
        EeeControl* e = EeeControl::getInstance();
        e->setFanMode(EeeControl::FanModeManual);

        // save in the settings
        ConfigHolder* c = ConfigHolder::getInstance();
        c->setFanManual(true);
    }

}

void ControlWindow::on_fanControlAuto_clicked(bool checked)
{
    // disable fanSpeed control
    if (checked) {
        ui.fanSpeed->setEnabled(false);

        // turn off manual fan speed control
        EeeControl* e = EeeControl::getInstance();
        e->setFanMode(EeeControl::FanModeAuto);
 
        // save in the settings
        ConfigHolder* c = ConfigHolder::getInstance();
        c->setFanManual(false);
    }
}

void ControlWindow::on_fanSpeed_valueChanged(int i)
{
    // react only when radiobutton fanControlManual is on
    if (ui.fanControlManual->isChecked()) {
        // set specified fan speed in percent

        EeeControl* e = EeeControl::getInstance();
        e->setFanSpeedPercent(i);

        // save value in the config
        ConfigHolder* c = ConfigHolder::getInstance();
        c->setFanSpeed(i);
    }
}


void ControlWindow::indicatorsStateChanged(unsigned int state)
{
    qDebug() << "Indicators state changed: " << state;

    QIcon* icon;
    if (state & CAPS_LOCK_MASK) {
        // turn on caps lock icon
        icon = capsLockOnIcon;
    } else {
        // turn off caps lock icon
        icon = capsLockOffIcon;
    }
    capsLockTrayIcon->setIcon(*icon);

    if (state & NUM_LOCK_MASK) {
        // turn on num lock icon
        icon = numLockOnIcon;
    } else {
        icon = numLockOffIcon;
        // turn off num lock icon
    }
    numLockTrayIcon->setIcon(*icon);
}

void ControlWindow::quit()
{
    QCoreApplication::quit();
}
